<html>

<style>
    * {
        margin: 0;
    }

    #content {
        color: white;
        position: absolute;
        left: -20px;
        top: -10px;
        white-space: pre-wrap;
        height: 200px;
        overflow: auto;
    }

    #tag, #tag3d{
        color: white;
        font-size: 20px;
    }
</style>

<script type="importmap">
	{
	  "imports": {
		"three": "../../three.js-r151/build/three.module.js",
		"three/addons/": "../../three.js-r151/examples/jsm/"
	  }
	}
</script>

<body>
    <div id="content">
        CSS2DRenderer不随物体一起旋转，始终直面我们，即平行于平面
        也不放大缩小
        
        css3drender可以随物体一起旋转，缩放
        适用场景：广告牌？
    </div>
    <div id="canvas"></div>

    <div id="tag">标签内容2D</div>
    <div id="tag3d">标签内容3D</div>


    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        // 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject
        import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
        // 引入CSS3渲染器CSS3DRenderer
        import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';


        // 1. 必须创建的三大件
        // 1.1 三维场景Scene, 类似创建了个世界，三维世界
        const scene = new THREE.Scene();
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        const material = new THREE.MeshBasicMaterial({ color: 'yellow' });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        // 添加辅助坐标系
        const axesHelper = new THREE.AxesHelper(5);
        scene.add(axesHelper);

        // 1.2 相机
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(3, 3, 3)

        // 1.3 渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        let canvasDom = document.getElementById("canvas");
        canvasDom.appendChild(renderer.domElement);


        // 3. html 2d标签
        let css2Renderer;
        {
            // 3.1 创建html元素
            // 3.2 转为css2dobject
            const div = document.getElementById('tag');
            // HTML元素转化为threejs的CSS2模型对象, 才能设置position
            const tag = new CSS2DObject(div);
            tag.position.set(1, 0, 1);
            scene.add(tag);

            // 3.3 创建一个CSS2渲染器CSS2DRenderer
            css2Renderer = new CSS2DRenderer();
            // 还得设置属性：width, height：canvas画布宽高度
            css2Renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(css2Renderer.domElement);
            // 其实默认创建了一个 div overflow: hidden; width: 680px; height: 577px;

            // 3.4 CSS2Renderer.domElement重新定位
            css2Renderer.domElement.style.position = 'absolute';
            css2Renderer.domElement.style.top = '0px';
            // 破解没法旋转
            // 方法一：让上层dom没有鼠标事件
            css2Renderer.domElement.style.pointerEvents = 'none';
            // 方法二：
            // 2. 设置相机控件轨道控制器OrbitControls
            new OrbitControls(camera, canvasDom);
            // new OrbitControls(camera, css2Renderer.domElement);

        }


        // 创建一个CSS3渲染器CSS3DRenderer
        let css3Renderer;
        {
            // 1. 创建元素
            // 2. 转为对象
            const div = document.getElementById('tag3d');
            // HTML元素转化为threejs的CSS2模型对象, 才能设置position
            const tag = new CSS3DObject(div);
            tag.position.set(-1, 0, 1);
            tag.scale.set(0.01, 0.01, 0.01);
            scene.add(tag);

            // 3. 创建渲染器
            css3Renderer = new CSS3DRenderer();
            css3Renderer.setSize(window.innerWidth, window.innerHeight);

            // 4. 重新定位 HTML标签<div id="tag"></div>外面父元素叠加到canvas画布上且重合
            css3Renderer.domElement.style.position = 'absolute';
            css3Renderer.domElement.style.top = '0px';
            //设置.pointerEvents=none，解决HTML元素标签对threejs canvas画布鼠标事件的遮挡
            css3Renderer.domElement.style.pointerEvents = 'none';
            document.body.appendChild(css3Renderer.domElement);
        }


        function render() {
            renderer.render(scene, camera);
            // 用法和webgl渲染器渲染方法类似
            css2Renderer.render(scene, camera);
            css3Renderer.render(scene, camera);
            requestAnimationFrame(render)
        }
        render();

        // 画布跟随窗口变化
        window.onresize = function () {
            const width = window.innerWidth;
            const height = window.innerHeight;
            // cnavas画布宽高度重新设置
            renderer.setSize(width, height);
            // HTML标签css2Renderer.domElement尺寸重新设置
            css2Renderer.setSize(width, height);
            camera.aspect = width / height;
            camera.updateProjectionMatrix();
        };


    </script>
</body>

</html>